home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / dm3_mst.zip / MSTRMIND.C < prev    next >
Text File  |  1990-04-06  |  40KB  |  1,274 lines

  1. /* ************************************************************************* */
  2. /*                                                                           */
  3. /*                           M A S T E R M I N D                             */
  4. /*                                                                           */
  5. /*                               Sample Door                                 */
  6. /*                                                                           */
  7. /*            by Michael W. Bayley (Mycroft RBBS) - March 1, 1988            */
  8. /*                                                                           */
  9. /* ************************************************************************* */
  10.  
  11.  
  12.  
  13. /* ************************************************************************* */
  14. /*                            PROGRAM HISTORY                                */
  15. /* ************************************************************************* */
  16. /* 03/01/88     Version 1.00                                                 */
  17. /* 04/06/90     Version 2.00  Upgrade to DMLIB 3.00 Alpha                    */
  18. /*                                                                           */
  19. /*                                                                           */
  20. /*                                                                           */
  21. /*                                                                           */
  22. /* ************************************************************************* */
  23.  
  24.  
  25.  
  26.  
  27. /* **************************** */
  28. /*      Linkage References      */
  29. /* **************************** */
  30.  
  31. #include <stdio.h>              /* standard header file */
  32. #include <stdlib.h>             /* standard library interface */
  33. #include <string.h>             /* string functions */
  34. #include <process.h>            /* process functions */
  35.  
  36. #include "dmdata.h"             /* doorware data structures */
  37.  
  38.  
  39.  
  40. /* **************************** */
  41. /*      Global Data Section     */
  42. /* **************************** */
  43.  
  44.  
  45. /* Flags & States */
  46.  
  47. int     games;                                  /* number of games played    */
  48. int     tscore;                                 /* total score               */
  49. int     score;                                  /* current score             */
  50.  
  51. int     codes[2][8];                            /* solution matrix           */
  52. int     matches;                                /* correct matches           */
  53. int     positions;                              /* correct positions         */
  54.  
  55. int     games;                                  /* current game number       */
  56. int     guess;                                  /* current guess number      */
  57.  
  58.  
  59. /* Players File structure */
  60.  
  61. struct  player_data
  62. {
  63.   char  name[32];                               /* Players name              */
  64.   long  games;                                  /* Number of games played    */
  65.   long  score;                                  /* Total turns used          */
  66.   char  game_date[12];                          /* Last date played          */
  67.   long  game_end;                               /* last time user played     */
  68.   long  day_time;                               /* time user played          */
  69.   int   day_games;                              /* games user played         */
  70. };
  71.  
  72. int     plrec;
  73. struct  player_data     player_info;
  74.  
  75. /* Buffers */
  76.  
  77. char    cyan[15];                               /* Cyan color string         */
  78. char    white[15];                              /* White color string        */
  79. char    grey[15];                               /* Grey color string         */
  80.  
  81. char    qbuff[81];                              /* line input buffer         */
  82. char    input_line[255];                        /* file input buffer         */
  83. char    color_code[9] = { "WROYGBVK" };         /* color codes               */
  84. char    code_str[6];                            /* solution code             */
  85. char    last_str[6];                            /* last players guess        */
  86. char    guess_str[6];                           /* players guess             */
  87.  
  88.  
  89. /* File Names & Titles */
  90.  
  91. char    mbanner1[81] = {"Mycroft Mastermind                                                  Version 1.00"};
  92. char    mbanner2[81] = {"                               Mycroft Mastermind                   Version 1.00"};
  93.  
  94.  
  95.  
  96. /* **************************** */
  97. /*      Program Code Section    */
  98. /* **************************** */
  99. /* **************************** */
  100. /*       Mastermind - Main      */
  101. /* **************************** */
  102.  
  103. /*
  104.  * This program assume a standard Mycroft command line
  105.  *
  106.  * MSTRMIND                     Local
  107.  * MSTRMIND node                Door monitor system
  108.  * MSTRMIND node path RBBS      RBBS 16.x system
  109.  * MSTRMIND node path QBBS      Quick BBS system
  110.  * MSTRMIND node path PCBOARD   PCBOARD system
  111.  * MSTRMIND node path WILDCAT   Wildcat system
  112.  */
  113.  
  114. main(argc ,argv)
  115.  
  116. int     argc;
  117. char    *argv[];
  118. {
  119. FS      rfd;                                    /* help file access structure*/
  120. int     line;                                   /* help line counter         */
  121. int     flow;                                   /* help flow control         */
  122. int     abort;                                  /* help abort flag           */
  123.  
  124. int     st;                                     /* return code status        */
  125. int     i, j;                                   /* work variables            */
  126. int     playing;                                /* game is active            */
  127. int     not_done, not_done1;                    /* while controls            */
  128.  
  129.  
  130.   /*
  131.    * Initialize
  132.    */
  133.  
  134.    dmtimer_open();                              /* Hook the timer            */
  135.    switch(argc)                                 /* Process BBS login         */
  136.    {
  137.      case 1:   /* Local */
  138.                st = read_bbs_info(-1, "\0", "\0");
  139.                break;
  140.      case 2:   /* Monitor */
  141.                st = read_bbs_info(atoi(argv[1]), "\0", "\0");
  142.                break;
  143.      case 4:   /* BBS */
  144.                st = read_bbs_info(atoi(argv[1]), argv[2], argv[3]);
  145.                break;
  146.      default:  /* Illegal */
  147.                report_error("Error - Illegal command line parameters.");
  148.                bye(1, 0);
  149.                break;
  150.    }
  151.  
  152.    switch(st)
  153.    {
  154.      case 0:    /* No error */
  155.                 break;
  156.      case -1:   /* Can't locate NODES.BBS */
  157.                 report_error("Error - Can't open NODES.BBS.");
  158.                 break;
  159.      case -2:   /* Can't find node record */
  160.                 report_error("Error - Can't read node record in NODES.BBS.");
  161.                 break;
  162.      case -3:   /* Can't identify comm port */
  163.                 report_error("Error - Can't identify comm port in NODES.BBS.");
  164.                 break;
  165.      case -4:   /* Illegal number of parameters */
  166.                 report_error("Error - Bad number of parameters in PORTS.BBS.\r\n");
  167.                 break;
  168.      case -5:   /* Illegal comm port id */
  169.                 report_error("Error - Bad comm port ID parameter in PORTS.BBS.\r\n");
  170.                 break;
  171.      case -6:   /* Illegal comm port address */
  172.                 report_error("Error - Bad comm port address parameter in PORTS.BBS.\r\n");
  173.                 break;
  174.      case -7:   /* Illegal IRQ number */
  175.                 report_error("Error - Bad IRQ number parameter in PORTS.BBS.\r\n");
  176.                 break;
  177.      case -8:   /* Illegal INT enable */
  178.                 report_error("Error - Bad access type parameter in PORTS.BBS.\r\n");
  179.                 break;
  180.      case -9:   /* Illegal handshake */
  181.                 report_error("Error - Bad handshake parameter in PORTS.BBS.\r\n");
  182.                 break;
  183.      case -10:  /* Illegal passthrough */
  184.                 report_error("Error - Bad passthrough parameter in PORTS.BBS.\r\n");
  185.                 break;
  186.      case -11:  /* Duplicate comm port definition */
  187.                 report_error("Error - Duplicate comm port definition in PORTS.BBS.\r\n");
  188.                 break;
  189.      case -12:  /* No defined port ids */
  190.                 report_error("Error - No defined ports in PORTS.BBS.\r\n");
  191.                 break;
  192.      case -13:  /* Port not defined */
  193.                 report_error("Error - Extended port not defined in PORTS.BBS.");
  194.                 break;
  195.      case -21:  /* Can't locate MESSAGES */
  196.                 report_error("Error - Can't open MESSAGES.");
  197.                 break;
  198.      case -22:  /* Can't read node record */
  199.                 report_error("Error - Can't read node record in MESSAGES.");
  200.                 break;
  201.      case -23:  /* Can't locate DORINFOx.DEF */
  202.                 report_error("Error - Can't open DORINFOx.DEF.");
  203.                 break;
  204.      case -24:  /* Can't read DORINFOx.DEF */
  205.                 report_error("Error - Can't read DORINFOx.DEF.");
  206.                 break;
  207.      case -31:  /* Can't locate PCBOARD.SYS */
  208.                 report_error("Error - Can't open PCBOARD.SYS.");
  209.                 break;
  210.      case -32:  /* Can't read PCBOARD.SYS */
  211.                 report_error("Error - Can't read PCBOARD.SYS.");
  212.                 break;
  213.      case -41:  /* Can't locate CALLINFO.BBS */
  214.                 report_error("Error - Can't open CALLINFO.BBS.");
  215.                 break;
  216.      case -42:  /* Can't read CALLINFO.BBS */
  217.                 report_error("Error - Can't read CALLINFO.BBS.");
  218.                 break;
  219.      case -51:  /* Can't locate DORINFOx.DEF */
  220.                 report_error("Error - Can't open DORINFOx.DEF.");
  221.                 break;
  222.      case -52:  /* Can't read DORINFOx.DEF */
  223.                 report_error("Error - Can't read DORINFOx.DEF.");
  224.                 break;
  225.      case -61:  /* Can't locate DOOR.SYS */
  226.                 report_error("Error - Can't open DOOR.SYS.");
  227.                 break;
  228.      case -62:  /* Can't read DOOR.SYS */
  229.                 report_error("Error - Can't read DOOR.SYS.");
  230.                 break;
  231.      case -71:  /* Can't locate CHAIN.TXT */
  232.                 report_error("Error - Can't open CHAIN.TXT.");
  233.                 break;
  234.      case -72:  /* Can't read CHAIN.TXT */
  235.                 report_error("Error - Can't read CHAIN.TXT.");
  236.                 break;
  237.      case -81:  /* Can't locate SFDOORS.DAT */
  238.                 report_error("Error - Can't open SFDOORS.DAT.");
  239.                 break;
  240.      case -82:  /* Can't read DORINFOx.DEF */
  241.                 report_error("Error - Can't read SFDOORS.DAT.");
  242.                 break;
  243.      case -83:  /* Can't locate SFMAIN.DAT */
  244.                 report_error("Error - Can't open SFMAIN.DAT.");
  245.                 break;
  246.      case -84:  /* Can't read SFMAIN.DAT */
  247.                 report_error("Error - Can't read SFMAIN.DAT.");
  248.                 break;
  249.      case -85:  /* Can't locate SFMESS.DAT */
  250.                 report_error("Error - Can't open SFMESS.DAT.");
  251.                 break;
  252.      case -86:  /* Can't read SFMESS.DAT */
  253.                 report_error("Error - Can't read SFMESS.DAT.");
  254.                 break;
  255.      case -87:  /* Can't locate SFFILE.DAT */
  256.                 report_error("Error - Can't open SFFILE.DAT.");
  257.                 break;
  258.      case -88:  /* Can't read SFFILE.DAT */
  259.                 report_error("Error - Can't read SFFILE.DAT.");
  260.                 break;
  261.      case -101: /* Can't access TIMEOFFx.DOR */
  262.                 report_error("Error - Can't access TIMEOFFx.DOR.");
  263.                 break;
  264.      case -102: /* Can't access NAMES.DOR */
  265.                 report_error("Error - Can't access NAMES.DOR.");
  266.                 break;
  267.      case 1:    /* Bad BBS type parameter */
  268.                 report_error("Error - Unrecognized BBS type.");
  269.                 break;
  270.      default:   /* Unknown error */
  271.                 sprintf(qbuff, "Error - Unrecognized return code [%d] from bbs_read_info().", st);
  272.                 report_error(qbuff);
  273.                 break;
  274.    }
  275.    if(st)
  276.      bye(1, 0);
  277.  
  278.  
  279.   /*
  280.    * Print Signon Screen
  281.    */
  282.  
  283.    print_string("Mycroft Mastermind\r\n");
  284.    print_string("Version 2.00  4/6/90\r\n");
  285.    print_string("by Michael W. Bayley\r\n");
  286.    print_string("Mycroft Systems BBS (408)927-0105\r\n");
  287.    print_string("\r\n");
  288.  
  289.    sleep(2);
  290.  
  291.  
  292.    /*
  293.     * Force snoop on and no paging
  294.     */
  295.  
  296.    bbs_node_info.snoop[0]       = ' ';
  297.    bbs_node_info.snoop[1]       = '1';
  298.    bbs_node_info.sysop_avail[0] = ' ';
  299.    bbs_node_info.sysop_avail[1] = '0';
  300.    bbs_node_info.sysop_annoy[0] = ' ';
  301.    bbs_node_info.sysop_annoy[1] = '0';
  302.  
  303.  
  304.    /*
  305.     * Now welcome the player
  306.     */
  307.  
  308.    print_string("  Welcome, %s\r\n", user_name);
  309.    print_string("  to Mycroft Mastermind\r\n", user_name);
  310.    sleep(3);
  311.  
  312.  
  313.   /*
  314.    * Read in the player record from player file
  315.    */
  316.  
  317.    get_player_info();
  318.  
  319.  
  320.   /*
  321.    * Test time controls
  322.    */
  323.  
  324.    strcpy(user_game_date, player_info.game_date);       /* Last date played  */
  325.    user_game_end  = player_info.game_end;       /* last time user played     */
  326.    user_day_time  = player_info.day_time;       /* time user played          */
  327.    user_day_games = player_info.day_games;      /* games user played         */
  328.  
  329.    st = time_controls("MSTRMIND.TIM");
  330.    switch(st)
  331.    {
  332.      case -3:   /* Insufficient security for time window */
  333.                 print_string("Error - Insufficient security for this time period.");
  334.                 print_string("        Try again later.");
  335.                 sleep(3);
  336.                 bye(1, 0);
  337.                 break;
  338.  
  339.      case -2:   /* Insufficient security */
  340.                 print_string("Error - Insufficient security!");
  341.                 print_string("        Check with SysOp.");
  342.                 sleep(3);
  343.                 bye(1, 0);
  344.                 break;
  345.  
  346.      case -1:   /* Bad read of file */
  347.                 report_error("Error - Reading time definitions.");
  348.                 sleep(3);
  349.                 break;
  350.  
  351.      case 0:    /* File is not being used */
  352.                 break;
  353.  
  354.      case 1:    /* All is OK */
  355.                 break;
  356.    }
  357.  
  358.    st = daily_controls();
  359.    switch(st)
  360.    {
  361.      case -3:   /* Exceeded daily time limit */
  362.                 print_string("Error - You have you all of your daily time.");
  363.                 print_string("        Try again tomorrow.");
  364.                 sleep(3);
  365.                 bye(1, 0);
  366.                 break;
  367.  
  368.      case -2:   /* Exceeded daily entry limit */
  369.                 print_string("Error - Daily run limit exceeded!");
  370.                 print_string("        Try again tomorrow.");
  371.                 sleep(3);
  372.                 bye(1, 0);
  373.                 break;
  374.  
  375.      case -1:   /* Isufficient wait */
  376.                 report_error("Error - You must wait longer before you can");
  377.                 print_string("        enter program, try later.");
  378.                 sleep(3);
  379.                 bye(1, 0);
  380.                 break;
  381.  
  382.      case 0:    /* All is OK */
  383.                 break;
  384.    }
  385.    player_info.day_time  = user_day_time;       /* time user played          */
  386.    player_info.day_games = user_day_games;      /* games user played         */
  387.  
  388.  
  389.   /*
  390.    * Get User Selected Graphics Mode
  391.    */
  392.  
  393.    sleep(3);                                    /* delay a while             */
  394.    if(remote_user == 0)
  395.    {
  396.      /*
  397.       * If game is local, get graphics mode
  398.       */
  399.  
  400.      not_done = 1;
  401.      while(not_done)
  402.      {
  403.        print_string("  Enter your graphics mode (N=none, A=ASCII grpahics, G=ANSI graphics): ");
  404.        io_linput(input_line);
  405.  
  406.        switch(input_line[0])
  407.        {
  408.          case 'N':        /* No graphics */
  409.          case 'n':
  410.                           user_graphics = 0;
  411.                           not_done = 0;
  412.                           break;
  413.          case 'A':        /* No graphics */
  414.          case 'a':
  415.                           user_graphics = 1;
  416.                           not_done = 0;
  417.                           break;
  418.          case 'G':        /* No graphics */
  419.          case 'g':
  420.                           user_graphics = 2;
  421.                           not_done = 0;
  422.                           break;
  423.          default:         /* Bad Entry */
  424.                           print_string(" Error - Bad response\r\n\r\n");
  425.                           break;
  426.        }
  427.      }
  428.    }
  429.  
  430.  
  431.   /*
  432.    * Display Game Banner
  433.    */
  434.  
  435.    if(remote_user)
  436.    {
  437.      i = 0;                                     /* Add player name to banner */
  438.      while((i < 18) && (user_name[i] != '\0'))
  439.      {
  440.        mbanner2[i] = user_name[i];
  441.        i++;
  442.      }
  443.      set_local_banner(mbanner2, WHITE, CYAN);   /* Deluxe game banner        */
  444.    }
  445.    else
  446.      set_local_banner(mbanner1, WHITE, CYAN);   /* Standard game banner      */
  447.  
  448.    put_local_banner();                          /* Show the banner           */
  449.  
  450.  
  451.    /*
  452.     * Set up colors
  453.     */
  454.  
  455.    if(user_graphics == 2)
  456.    {
  457.      sprintf(cyan, "\033[1;36;40m");            /* Bright Cyan for color     */
  458.      sprintf(white, "\033[1;37;40m");           /* Bright White for color    */
  459.      sprintf(grey, "\033[0;37;40m");            /* Dim grey for standard     */
  460.    }
  461.    else
  462.    {
  463.      sprintf(cyan, "\0");                       /* No color use null string  */
  464.      sprintf(white, "\0");                      /* No color use null string  */
  465.      sprintf(grey, "\0");                       /* No color use null string  */
  466.    }
  467.  
  468.  
  469.   /*
  470.    * Display Rules if Requested
  471.    */
  472.  
  473.    game_header();
  474.  
  475.    print_string(white);
  476.    print_string("  Do you need instructions (Y/[N])? ");
  477.    print_string(grey);
  478.    io_linput(qbuff);
  479.  
  480.    if(test_error(qbuff))
  481.      bye(1,0);
  482.  
  483.    if(strcmp("Y", strupr(qbuff)) == 0)
  484.    {
  485.      switch(user_graphics)
  486.      {
  487.        case 0:    /* No Graphics */
  488.                   strcpy(rfd.name, "MSTRMIND.HPN");
  489.                   break;
  490.        case 1:    /* ASCII Graphics */
  491.                   strcpy(rfd.name, "MSTRMIND.HPA");
  492.                   break;
  493.        case 2:    /* ANSIGraphics */
  494.                   strcpy(rfd.name, "MSTRMIND.HPG");
  495.                   break;
  496.      }
  497.      st = file_open(&rfd, FREAD, FBINARY, FNOCREATE);
  498.      if(st == 0)
  499.      {
  500.        line = 0;
  501.        flow = 1;
  502.        abort = 0;
  503.  
  504.        /*
  505.         * Print help till aborted or done
  506.         */
  507.  
  508.        while((fgets(input_line, 255, rfd.fd) != 0) && (abort == 0))
  509.        {
  510.          if(flow)
  511.            i = print_metered(&line, input_line, qbuff);
  512.          else
  513.          {
  514.            i = print_string(input_line);
  515.            strcpy(qbuff, "\0");
  516.          }
  517.  
  518.          switch(i)                              /* process results           */
  519.          {
  520.            case 0:      /* Normal operation */
  521.                         break;
  522.            case 1:      /* NS enetered */
  523.                         flow = 0;               /* turn off pausing          */
  524.                         break;
  525.            case 2:      /* N enetered */
  526.                         abort = 1;              /* stop displaying           */
  527.                         break;
  528.            case -1:     /* Unsure response */
  529.                         if(test_error(qbuff))   /* abort if line problems    */
  530.                         {
  531.                           file_close(&rfd);     /* close the file            */
  532.                           bye(1,0);             /* adios                     */
  533.                         }
  534.          }
  535.        }
  536.        file_close(&rfd);                        /* close out the file        */
  537.      }
  538.      else
  539.        report_error("  Error - Can't find rules file");
  540.    }
  541.  
  542.  
  543.    /*
  544.     * Wait for OK to start
  545.     */
  546.  
  547.    print_string(white);
  548.    print_string("                            Press [ENTER] to begin...");
  549.    print_string(grey);
  550.    io_lxinput(qbuff);
  551.  
  552.    if(test_error(qbuff))
  553.      bye(1,0);
  554.  
  555.    backup(strlen(qbuff) + 53);
  556.  
  557.  
  558.   /*
  559.    * Note:      The game employs color strings and cursor positioning.
  560.    *
  561.    *            If the users graphics does not support this he will
  562.    *            by default get grey text, and the game will scroll as
  563.    *            it is played.
  564.    *
  565.    *            If he does have ANSI capability he gets a single screen
  566.    *            with color.
  567.    */
  568.  
  569.   /*
  570.    * Setup the game
  571.    */
  572.  
  573.   games   = 0;                                  /* no games completed        */
  574.   tscore  = 0;                                  /* no score yet              */
  575.   playing = 1;                                  /* playing the game          */
  576.  
  577.   while(playing)
  578.   {
  579.     game_header();                              /* redisplay game header     */
  580.     games++;                                    /* one more game             */
  581.     score = 250;                                /* 200 points to start       */
  582.     guess = 1;                                  /* start with guess # 1      */
  583.  
  584.     position_cursor(16, 8);                     /* Show game number          */
  585.     print_string(white);
  586.     print_string("Game number: ");
  587.     print_string(grey);
  588.     print_string("%2d\r\n", games);
  589.  
  590.     strcpy(last_str, "\0");                     /* no last guess             */
  591.  
  592.  
  593.     for(i = 0 ; i < 5 ; i++)                    /* pick the 5 digit code     */
  594.     {
  595.       j = rand() & 0x07;                        /* entry is one of 8 colors  */
  596.       code_str[i] = color_code[j];              /* select the letter         */
  597.     }
  598.     code_str[5] = '\0';                         /* null terminate            */
  599.  
  600.  
  601.     /*
  602.      * The main game loop
  603.      */
  604.  
  605.     not_done = 1;
  606.     while(not_done)
  607.     {
  608.       /*
  609.        * Display play status
  610.        */
  611.  
  612.       position_cursor(45, 8);                   /* Show turn number          */
  613.       print_string(white);
  614.       print_string("Guess number: ");
  615.       print_string(grey);
  616.       print_string("%2d\r\n", guess);
  617.  
  618.       position_cursor(28, 11);                  /* Show last guess           */
  619.       print_string(white);
  620.       print_string("Last guess was: ");
  621.       print_string(grey);
  622.       print_string(last_str);
  623.       print_string("\r\n");
  624.  
  625.  
  626.       /*
  627.        * Show prompt & get response
  628.        */
  629.  
  630.       position_cursor(28, 12);                  /* Get current guess         */
  631.       print_string(white);
  632.       print_string("Current guess : ");
  633.       eol_display();
  634.       print_string(grey);
  635.       io_linput(qbuff);
  636.  
  637.  
  638.       /*
  639.        * Abort if remote error
  640.        */
  641.  
  642.       position_cursor(0, 22);                 /* Assume a message is comming */
  643.       if(test_error(qbuff))
  644.       {
  645.         games--;
  646.         if(games)
  647.           bye(0, (tscore * 10) / games);
  648.         else
  649.           bye(1, 0);
  650.       }
  651.       position_cursor(0, 22);                   /* Erase incase time warning */
  652.       eol_display();
  653.       print_string("\r\n");
  654.  
  655.  
  656.       /*
  657.        * Parse & Dispatch Command
  658.        */
  659.  
  660.       if(strcmp("QUIT", strupr(qbuff)) == 0)    /* Quit command              */
  661.       {
  662.         position_cursor(0, 22);                 /* set on communications line*/
  663.         print_string(white);
  664.         print_string("Sure you want to quit (Y/[N])? ");
  665.         print_string(grey);
  666.         io_linput(qbuff);
  667.  
  668.         position_cursor(0, 22);               /* Assume a message is comming */
  669.         if(test_error(qbuff))
  670.         {
  671.           games--;
  672.           if(games)
  673.             bye(0, (tscore * 10) / games);
  674.           else
  675.             bye(1, 0);
  676.         }
  677.  
  678.         position_cursor(0, 22);                 /* Erase incase time warning */
  679.         eol_display();
  680.  
  681.         if(strcmp("Y", strupr(qbuff)) == 0)     /* Exit if YES               */
  682.         {
  683.           games--;
  684.           if(games)
  685.             bye(0, (tscore * 10) / games);
  686.           else
  687.             bye(1, 0);
  688.         }
  689.       }
  690.  
  691.       else if(strcmp("PAGE", strupr(qbuff)) == 0)       /* Page command      */
  692.       {
  693.         if(page_operator())
  694.           chat_mode();
  695.         else
  696.         {
  697.           position_cursor(0, 22);
  698.           print_string("Sorry, SysOp not available\r\n");
  699.           sleep(3);
  700.           position_cursor(0, 22);
  701.           eol_display();
  702.         }
  703.       }
  704.  
  705.       else                                      /* Assume a code was input   */
  706.       {
  707.         if(strlen(qbuff) != 5)
  708.         {
  709.           /*
  710.            * Code must be 5 digits
  711.            */
  712.  
  713.           position_cursor(0, 22);
  714.           print_string(white);
  715.           print_string("Error - Bad number of code entries.\r\n");
  716.           sleep(5);
  717.           position_cursor(0, 22);
  718.           eol_display();
  719.         }
  720.         else
  721.         {
  722.           /*
  723.            * Guarantee upper case
  724.            */
  725.  
  726.           for(i = 0 ; i < 5 ; i++)              /* Strip out bit 5 in each   */
  727.             guess_str[i] = qbuff[i] & 0x5f;
  728.           guess_str[i] = '\0';                  /* Null terminate the string */
  729.  
  730.  
  731.           /*
  732.            * Now count each color set
  733.            */
  734.  
  735.           for(i = 0 ; i < 8 ; i++)              /* Init the solution matrix  */
  736.           {
  737.             codes[0][i] = 0;
  738.             codes[1][i] = 0;
  739.           }
  740.  
  741.           for(i = 0 ; i < 5 ; i++)              /* do all five entries       */
  742.           {
  743.             switch(code_str[i])                 /* count the solution codes  */
  744.             {
  745.               case 'W': /* White */
  746.                         codes[0][0] += 1;
  747.                         break;
  748.               case 'R': /* Red */
  749.                         codes[0][1] += 1;
  750.                         break;
  751.               case 'O': /* Orange */
  752.                         codes[0][2] += 1;
  753.                         break;
  754.               case 'Y': /* Yellow */
  755.                         codes[0][3] += 1;
  756.                         break;
  757.               case 'G': /* Green */
  758.                         codes[0][4] += 1;
  759.                         break;
  760.               case 'B': /* Blue */
  761.                         codes[0][5] += 1;
  762.                         break;
  763.               case 'V': /* Violet */
  764.                         codes[0][6] += 1;
  765.                         break;
  766.               case 'K': /* Black */
  767.                         codes[0][7] += 1;
  768.                         break;
  769.             }
  770.  
  771.             switch(guess_str[i])                /* count the player codes    */
  772.             {
  773.               case 'W': /* White */
  774.                         codes[1][0] += 1;
  775.                         break;
  776.               case 'R': /* Red */
  777.                         codes[1][1] += 1;
  778.                         break;
  779.               case 'O': /* Orange */
  780.                         codes[1][2] += 1;
  781.                         break;
  782.               case 'Y': /* Yellow */
  783.                         codes[1][3] += 1;
  784.                         break;
  785.               case 'G': /* Green */
  786.                         codes[1][4] += 1;
  787.                         break;
  788.               case 'B': /* Blue */
  789.                         codes[1][5] += 1;
  790.                         break;
  791.               case 'V': /* Violet */
  792.                         codes[1][6] += 1;
  793.                         break;
  794.               case 'K': /* Black */
  795.                         codes[1][7] += 1;
  796.                         break;
  797.             }
  798.           }
  799.  
  800.  
  801.           /*
  802.            * Now calculate matches
  803.            */
  804.  
  805.           matches = 0;
  806.           for(i = 0 ; i < 8 ; i++)              /* for each color            */
  807.           {
  808.             if(codes[0][i] >= codes[1][i])
  809.               matches += codes[1][i];           /* use player count          */
  810.             else
  811.               matches += codes[0][i];           /* use solution count        */
  812.           }
  813.  
  814.  
  815.           /*
  816.            * Now calculate positions
  817.            */
  818.  
  819.           positions = 0;
  820.           for(i = 0 ; i < 5 ; i++)              /* for each code entry       */
  821.           {
  822.             if(guess_str[i] == code_str[i])     /* if codes match            */
  823.               positions++;                      /* one more correct pos.     */
  824.           }
  825.  
  826.  
  827.           /*
  828.            * Update display to matches & positions
  829.            */
  830.  
  831.           position_cursor(16, 16);              /* Show matches              */
  832.           print_string(white);
  833.           print_string("Matched codes: ");
  834.           print_string(grey);
  835.           print_string("%d\r\n", matches);
  836.  
  837.           position_cursor(45, 16);              /* Show positions            */
  838.           print_string(white);
  839.           print_string("Correct order: ");
  840.           print_string(grey);
  841.           print_string("%d\r\n", positions);
  842.  
  843.  
  844.           /*
  845.            * Test for final solution
  846.            */
  847.  
  848.           if(positions == 5)
  849.           {
  850.             /*
  851.              * Player has guessed the code
  852.              */
  853.  
  854.             position_cursor(0, 21);             /* Let him know he won      */
  855.             print_string(white);
  856.             print_string("Congratulations, you guessed the code.\r\n");
  857.             print_string("You have earned %d points for this game\r\n", score);
  858.             print_string(grey);
  859.             sleep(6);
  860.             position_cursor(0, 21);
  861.             eol_display();
  862.             position_cursor(0, 22);
  863.             eol_display();
  864.  
  865.  
  866.             /*
  867.              * Adjust his total score & check to play another game
  868.              */
  869.  
  870.             tscore  += score;
  871.             not_done = 0;
  872.  
  873.             position_cursor(0, 22);
  874.             print_string(white);
  875.             print_string("Play another (Y/[N]): ");
  876.             print_string(grey);
  877.  
  878.             io_lxinput(qbuff);
  879.             if(test_error(qbuff))
  880.               bye(0, (tscore * 10) / games);
  881.  
  882.             backup(strlen(qbuff) + 53);
  883.  
  884.             if((qbuff[0] == 'Y') || (qbuff[0] == 'y'))
  885.               playing = 1;
  886.             else
  887.               playing = 0;
  888.           }
  889.           else
  890.           {
  891.             /*
  892.              * Bump the turn counter
  893.              * & remove possible points
  894.              */
  895.  
  896.             guess++;
  897.             strcpy(last_str, guess_str);
  898.             if(score > 0)
  899.               score -= 10;
  900.           }
  901.         }
  902.       }
  903.     }
  904.   }
  905.  
  906.   /*
  907.    * Time to exit
  908.    */
  909.  
  910.   bye(0, (tscore * 10) / games);
  911. }
  912.  
  913.  
  914. /* **************************** */
  915. /*       Subroutine Section     */
  916. /* **************************** */
  917. /* **************************** */
  918. /*          Game Header         */
  919. /* **************************** */
  920.  
  921. game_header()
  922. {
  923.    cls_display();
  924.    print_string("\r\n");
  925.  
  926.    switch(user_graphics)
  927.    {
  928.      case 0:    /* No Grahics */
  929.                 print_string("===============================================================================\r\n");
  930.                 print_string("\r\n");
  931.                 print_string("                      M Y C R O F T   M A S T E R M I N D \r\n");
  932.                 print_string("\r\n");
  933.                 print_string("===============================================================================\r\n");
  934.                 break;
  935.      case 1:    /* ASCII Grahics */
  936.                 print_string("╔═════════════════════════════════════════════════════════════════════════════╗\r\n");
  937.                 print_string("║                                                                             ║\r\n");
  938.                 print_string("║                     M Y C R O F T   M A S T E R M I N D                     ║\r\n");
  939.                 print_string("║                                                                             ║\r\n");
  940.                 print_string("╚═════════════════════════════════════════════════════════════════════════════╝\r\n");
  941.                 break;
  942.      case 2:    /* ANSI Grahics */
  943.      print_string("\033[1;36;40m");
  944.                 print_string("\033[1;36;40m╔═════════════════════════════════════════════════════════════════════════════╗\r\n");
  945.                 print_string("\033[1;36;40m║                                                                             ║\r\n");
  946.                 print_string("\033[1;36;40m║                     \033[1;37;40mM Y C R O F T   M A S T E R M I N D                     \033[1;36;40m║\r\n");
  947.                 print_string("\033[1;36;40m║                                                                             ║\r\n");
  948.                 print_string("\033[1;36;40m╚═════════════════════════════════════════════════════════════════════════════╝\r\n");
  949.                 break;
  950.    }
  951.    print_string("\r\n");
  952.    print_string(grey);
  953.    return(0);
  954. }
  955.  
  956.  
  957. /* **************************** */
  958. /*   Test for Error Condition   */
  959. /* **************************** */
  960.  
  961. test_error(string)
  962.  
  963. char    *string;
  964. {
  965.    if(strcmp(string, "~NO_CARRIER") == 0)
  966.    {
  967.      print_string("ERROR - NO CARRIER, TERMINATING GAME!!!");
  968.      sleep(3);
  969.      return(-1);
  970.    }
  971.    if(strcmp(string, "~NOT_ACTIVE") == 0)
  972.    {
  973.      print_string("ERROR - NO TERMINAL ACTIVITY, TERMINATING GAME!!!");
  974.      sleep(3);
  975.      return(-1);
  976.    }
  977.    if(strcmp(string, "~TIME_WARNING") == 0)
  978.    {
  979.      print_string("WARNING - LESS THAN 5 MINUTES OF CONNECT TIME LEFT!!!");
  980.      sleep(3);
  981.      return(0);
  982.    }
  983.    if(strcmp(string, "~TIMEOUT") == 0)
  984.    {
  985.      print_string("ERROR - YOU HAVE USED ALL YOUR CONNECT TIME!!!");
  986.      sleep(3);
  987.      return(-1);
  988.    }
  989.    return(0);
  990. }
  991.  
  992.  
  993. /* **************************** */
  994. /*      Report Fatal Error      */
  995. /* **************************** */
  996.  
  997. report_error(string)
  998.  
  999. char    *string;
  1000. {
  1001. FS      efd;
  1002. int     st;
  1003.  
  1004.   /* Add error to end of file MSTRMIND.ERR */
  1005.  
  1006.   strcpy(efd.name, "MSTRMIND.ERR");
  1007.   st = file_open(&efd, FAPPEND, FTEXT, FCREATE);
  1008.   if(st == 0)
  1009.   {
  1010.     fprintf(efd.fd, "%s\n", string);
  1011.     file_close(&efd);
  1012.   }
  1013.  
  1014.   /* Also report error to virtual console */
  1015.  
  1016.   print_string(string);
  1017.   print_string("\r\n");
  1018.   sleep(3);
  1019.   return(0);
  1020. }
  1021.  
  1022.  
  1023. /* **************************** */
  1024. /*   Return points to Monitor   */
  1025. /* **************************** */
  1026.  
  1027. bye(flag, score)
  1028.  
  1029. int     flag;
  1030. int     score;
  1031. {
  1032.    if(flag == 0)
  1033.    {
  1034.      /*
  1035.       * Update player record and write it out
  1036.       */
  1037.  
  1038.       put_player_info();
  1039.  
  1040.  
  1041.      /*
  1042.       * Show player his stats
  1043.       */
  1044.  
  1045.       cls_display();
  1046.       game_header();
  1047.  
  1048.       print_string(white);
  1049.       print_string("Todays totals\r\n");
  1050.       print_string("-------------\r\n");
  1051.       print_string("Total games  : ");
  1052.       print_string(grey);
  1053.       print_string("%d\r\n", games);
  1054.  
  1055.       print_string(white);
  1056.       print_string("Total score  : ");
  1057.       print_string(grey);
  1058.       print_string("%d\r\n", tscore);
  1059.  
  1060.       print_string(white);
  1061.       print_string("Average score: ");
  1062.       print_string(grey);
  1063.       print_string("%d\r\n", tscore / games);
  1064.       print_string("\r\n");
  1065.  
  1066.  
  1067.       if(remote_user)
  1068.       {
  1069.         print_string(white);
  1070.         print_string("Overall totals\r\n");
  1071.         print_string("--------------\r\n");
  1072.         print_string("Total games  : ");
  1073.         print_string(grey);
  1074.         print_string("%d\r\n", player_info.games);
  1075.  
  1076.         print_string(white);
  1077.         print_string("Total score  : ");
  1078.         print_string(grey);
  1079.         print_string("%d\r\n", player_info.score);
  1080.  
  1081.         print_string(white);
  1082.         print_string("Average score: ");
  1083.         print_string(grey);
  1084.         print_string("%d\r\n", player_info.score / player_info.games);
  1085.       }
  1086.  
  1087.       if(mon_active)
  1088.       {
  1089.         print_string(white);
  1090.         print_string("Door points: ");
  1091.         print_string(grey);
  1092.         print_string("%d\r\n", (tscore * 10) / games);
  1093.       }
  1094.  
  1095.       sleep(6);
  1096.    }
  1097.  
  1098.    print_string(grey);
  1099.    print_string("\r\n");
  1100.    print_string("\r\n");
  1101.    print_string("\r\n");
  1102.  
  1103.    io_close();                                /* Release resources           */
  1104.    dmtimer_close();
  1105.  
  1106.    mon_write(user_node, score);               /* Exit via monitor if present */
  1107.    mon_exit(user_node);
  1108.  
  1109.    exit(flag);
  1110. }
  1111.  
  1112.  
  1113. /* **************************** */
  1114. /*      Get player record       */
  1115. /* **************************** */
  1116.  
  1117. get_player_info()
  1118. {
  1119. FS      plfs;
  1120. int     new_player;
  1121. int     not_done;
  1122.  
  1123.   /*
  1124.    * Only if remote game.
  1125.    */
  1126.  
  1127.    if(remote_user == 0)
  1128.      return(0);
  1129.  
  1130.  
  1131.   /*
  1132.    * Open up the player file.
  1133.    */
  1134.  
  1135.    new_player = 0;
  1136.    strcpy(plfs.name, "MSTRMIND.DAT");
  1137.  
  1138.    if(file_open(&plfs, FREAD, FBINARY, FNOCREATE))
  1139.      new_player = 1;
  1140.    else
  1141.    {
  1142.     /*
  1143.      * Read it in
  1144.      */
  1145.  
  1146.      plrec      = 0;
  1147.      new_player = 0;
  1148.      not_done   = 1;
  1149.      while(not_done)
  1150.      {
  1151.        if(read(plfs.fh, &player_info, sizeof(struct player_data)) != sizeof(struct player_data))
  1152.        {
  1153.          new_player = 1;
  1154.          not_done   = 0;
  1155.        }
  1156.        else
  1157.        {
  1158.          if(strcmp(strupr(user_name), strupr(player_info.name)) == 0)
  1159.            not_done = 0;
  1160.          else
  1161.            plrec++;
  1162.        }
  1163.      }
  1164.      file_close(&plfs);
  1165.    }
  1166.  
  1167.   /*
  1168.    * Init the structure if new player
  1169.    */
  1170.  
  1171.    if(new_player)
  1172.    {
  1173.      strcpy(player_info.name, user_name);       /* Players name              */
  1174.      player_info.games = 0L;                    /* Number of games played    */
  1175.      player_info.score = 0L;                    /* Total turns used          */
  1176.      strcpy(player_info.game_date, "Jan 01 1900");   /* Last date played     */
  1177.      player_info.game_end  = 0L;                /* last time user played     */
  1178.      player_info.day_time  = 0L;                /* time user played          */
  1179.      player_info.day_games = 0;                 /* games user played         */
  1180.      plrec = -1;
  1181.    }
  1182.  
  1183.   return(0);
  1184. }
  1185.  
  1186.  
  1187. /* **************************** */
  1188. /*      Put player record       */
  1189. /* **************************** */
  1190.  
  1191. put_player_info()
  1192. {
  1193. long    lseek();
  1194. long    cur_time();
  1195.  
  1196. FS      plfs;
  1197. long    ut;
  1198. char    tbuf[12];
  1199.  
  1200.  
  1201.   /*
  1202.    * Only if remote game.
  1203.    */
  1204.  
  1205.    if(remote_user == 0)
  1206.      return(0);
  1207.  
  1208.  
  1209.   /*
  1210.    * Open up the player file.
  1211.    */
  1212.  
  1213.    strcpy(plfs.name, "MSTRMIND.DAT");
  1214.  
  1215.    if(file_open(&plfs, FAPPEND, FBINARY, FCREATE))
  1216.    {
  1217.      report_error("Error - Can't access player file.");
  1218.      return(1);
  1219.    }
  1220.    else
  1221.    {
  1222.     /*
  1223.      * Seek the record
  1224.      */
  1225.  
  1226.      if(plrec != -1)
  1227.      {
  1228.        /* Go to players record */
  1229.  
  1230.        if(lseek(plfs.fh, (long)(plrec) * sizeof(struct player_data), 0) == -1)
  1231.        {
  1232.          report_error("Error - Can't seek record.");
  1233.          return(1);
  1234.        }
  1235.      }
  1236.  
  1237.    /*
  1238.     * Update the information
  1239.     */
  1240.  
  1241.     player_info.games += games;                 /* Number of games played    */
  1242.     player_info.score += tscore;                /* Total turns used          */
  1243.     get_date(player_info.game_date);            /* Last date played          */
  1244.     player_info.game_end  = cur_time();         /* last time user played     */
  1245.     if(player_info.game_end < user_signon)
  1246.       ut = player_info.game_end + (24L * 60L * 60L);
  1247.     else
  1248.       ut = player_info.game_end;
  1249.     player_info.day_time += ut - user_signon;   /* time user played          */
  1250.     player_info.day_games++;                    /* games user played         */
  1251.  
  1252.  
  1253.    /*
  1254.     * Write it out
  1255.     */
  1256.  
  1257.     if(write(plfs.fh, &player_info, sizeof(struct player_data)) != sizeof(struct player_data))
  1258.     {
  1259.       report_error("Error - Can't write record.");
  1260.       file_close(&plfs);
  1261.       return(1);
  1262.     }
  1263.     file_close(&plfs);
  1264.   }
  1265.  
  1266.   /*
  1267.    * Exit to caller
  1268.    */
  1269.  
  1270.    return(0);
  1271. }
  1272.  
  1273.  
  1274.